package nr.nodehost.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import nr.nodehost.model.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import nr.nodehost.Dispatcher;
import nr.nodehost.NodeHostApplication;
import nr.nodehost.SchemaExecutor;
import nr.nodehost.Utils;
import nr.nodehost.model.Component;
import nr.nodehost.service.AsyncTaskService;
import nr.nodehost.service.ComponentService;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController

public class NodeHostController {
	@Value("${context.schema-run-dir}")
	private String schemaRunDir;
    @Autowired
    private ComponentService componentService;
    @Autowired
    private AsyncTaskService taskService;
    @Autowired
    private Dispatcher dispatcher;

//	Map<Integer, List<Process>> IdProcess = new HashMap<>();

    @RequestMapping("/test")
    @ResponseBody
    public JSONObject send(String name) {
    	JSONObject result=new JSONObject();
    	result.put("name",name);
    	List<Component> components=componentService.listAll();
    	result.put("count", components.size());
        return result;
    }
    
    @RequestMapping("/runSchema")
    @ResponseBody
    public JSONObject runSchema(@RequestBody JSONObject schema) {
    	System.out.println(schema);
    	JSONObject result=new JSONObject();
		System.out.println("Into runSchema！！！");
    	SchemaExecutor schemaExecutor=dispatcher.getSchemaExecutor(schema.getInt("id"));
    	if(schemaExecutor==null) {
//			List<Process> ProcessList = new ArrayList<>();
//			IdProcess.put(schema.getInt("id"),ProcessList);
			System.out.println("runSchema！！！");
    		taskService.runSchema(schema);
			System.out.println("#############runSchema完成！！！");
    		result.put("code", 0);
        	result.put("info", "success");
    	}
    	else {
    		result.put("code", 2);
            result.put("info", "can't run schema");
    	}

        return result;
    }
    
    @RequestMapping("/stopSchema")
    @ResponseBody
    public JSONObject stopSchema(int schemaId) {
    	System.out.println(schemaId);
//		List<Process> ProcessList = IdProcess.get(schemaId);

//		System.out.println(ProcessList);

    	JSONObject result=dispatcher.stopSchemaExecutor(schemaId);

        return result;
    }
    
    @RequestMapping("/pauseSchema")
    @ResponseBody
    public JSONObject pauseSchema(int schemaId) {
    	System.out.println(schemaId);
    	JSONObject result=dispatcher.pauseSchemaExecutor(schemaId);
    	
        return result;
    }
    
    @RequestMapping("/resumeSchema")
    @ResponseBody
    public JSONObject resumeSchema(int schemaId) {
    	System.out.println(schemaId);
    	JSONObject result=dispatcher.resumeSchemaExecutor(schemaId);
    	
        return result;
    }
    
    @RequestMapping("/updateSchemaParam")
    @ResponseBody
    public JSONObject updateSchemaParam(@RequestBody JSONObject updateParamObject) {
    	JSONObject result=new JSONObject();
    	try{
    		int schemaId=updateParamObject.getInt("schemaId");
    	
    		JSONArray params=updateParamObject.getJSONArray("params");
    		System.out.println(schemaId);
    	
    		SchemaExecutor schemaExecutor=dispatcher.getSchemaExecutor(schemaId);
    		if(schemaExecutor!=null) {
    			schemaExecutor.updateSchemaParam(params);
    			result.put("code", 0);
    		}
    		else {
    			result.put("code", 1);
    			result.put("info", "no such schema.");
    		}
    	}
    	catch(Exception e) {
    		result.put("code", 2);
    		result.put("info", "update parameter fail.");
    		e.printStackTrace();
    	}
        return result;
    }
    
    @RequestMapping("/getComponentResourceUsage")
    @ResponseBody
    public JSONObject getComponentResourceUsage(HttpServletRequest request,int schemaId,String componentId,HttpServletResponse response) {
    	JSONObject usage=Utils.getComponentResourceUsage(schemaRunDir, schemaId, componentId);
    	return usage;
    }
    
    @RequestMapping("/getSchemaResourceUsage")
    @ResponseBody
    public JSONObject getSchemaResourceUsage(HttpServletRequest request,int schemaId,HttpServletResponse response) {
    	JSONObject usage=Utils.getSchemaResourceUsage(schemaRunDir, schemaId);
    	return usage;
    }
    
    @RequestMapping("/downloadOutput")
    public void downloadOutput(HttpServletRequest request,int schemaId,String componentId,String port,HttpServletResponse response) {
    	try{
    		//System.out.println(schemaId);
    		File componentOutputDir=new File(schemaRunDir+"/"+schemaId+"/"+componentId+"/output");
    		if(componentOutputDir.exists()) {
    			// create new filename filter
    	         FilenameFilter filter = new FilenameFilter() {
    	            @Override
    	            public boolean accept(File dir, String name) {
    	               if(name.startsWith(port)){
    	                  return true;
    	               }
    	               return false;
    	            }
    	         };
    			String[] files=componentOutputDir.list(filter);
    			if(files.length>0) {
    				Arrays.sort(files);
    				File outputFile=new File(schemaRunDir+"/"+schemaId+"/"+componentId+"/output/"+files[files.length-1]);
    				 //设置文件下载头  
        	        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(files[files.length-1],"UTF-8"));    
        	        //1.设置文件ContentType类型，这样设置，会自动判断下载文件类型    
        	        response.setContentType("multipart/form-data");   
        	        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());  
        	        FileInputStream fis = new FileInputStream(outputFile);
        	        byte[] data=new byte[(int)outputFile.length()];
        	        fis.read(data);
        	        out.write(data);
        	        out.close();
        	        fis.close();
        	        data=null;
    			}
    			else
    				response.sendError(HttpServletResponse.SC_NOT_FOUND, "outputfile invalid");
    		}
    	}
    	catch(Exception e) {
    		e.printStackTrace();
    	}
    }
}
